package org.raymond.iworks.core.holder;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.raymond.iworks.apis.common.Result;
import org.raymond.iworks.commons.utils.ErrorUtil;
import org.raymond.iworks.core.logger.interceptor.LoggingInterceptor;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class OkHttpTemplate {

    private OkHttpTemplate(){}

    private static final OkHttpClient okClient = new OkHttpClient().newBuilder()
            .connectTimeout(20, TimeUnit.SECONDS)
            .readTimeout(20, TimeUnit.SECONDS)
            .writeTimeout(60, TimeUnit.SECONDS)
            //.callTimeout(120, TimeUnit.SECONDS)
            .connectionPool(new ConnectionPool(5,5,TimeUnit.MINUTES))
            .addInterceptor(new LoggingInterceptor())
            .build();

    public <T> Result call(String url, String method, Object input, Class<T> responseType){
        OkHttpClient client = okClient;
        JSONObject jsonObject = JSONUtil.parseObj(JSONUtil.toJsonStr(input));
        RequestBody body = buildRequestBody(jsonObject);
        Request request = new Request.Builder().url(url).method(method, body).build();

        Result result = null;
        try{
            Response response = client.newCall(request).execute();
            String responseBody = response.body().string();
            if(JSONUtil.isTypeJSONObject(responseBody)){
                T data = JSONUtil.toBean(responseBody, responseType);
                result = Result.success(data);
            }if(JSONUtil.isTypeJSONArray(responseBody)){
                List<T> data = JSONUtil.toList(responseBody, responseType);
                result = Result.success(data);
            }else{
                result = Result.error(responseBody);
            }
        }catch(IOException e){
            log.error("client error:{}", ErrorUtil.getErrorLog(e));
        }
        return result;
    }

    private RequestBody buildRequestBody(JSONObject jsonObject){
        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        builder.setType(MediaType.parse("multipart/form-data"));

        for(String key : jsonObject.keySet()){
            Object value = jsonObject.get(key);
            if(value==null) continue;
            if(value instanceof JSONObject || value instanceof JSONArray){
                builder.addFormDataPart(key, JSONUtil.toJsonStr(value));
            }else{
                builder.addFormDataPart(key, String.valueOf(value));
            }
        }
        return builder.build();
    }
}
